/**
 * Compositor de Layout
 * Gerencia a composicao/modelagem do layout de um mapa
 *
 * @this {LayoutComposer}
 * @version
 */

function LayoutComposer() {

    /**
     * Variaveis
     */
    var _projectContent = [];
    var _oLayout = null;
    var _oSelectedElement = null;
    var _oClassOwner = this;

    /**
     * Inicializa o objeto da classe
     */
    this.init = function() {

        _oLayout = new Layout();
    }

    /**
     * Funcoes
     */
    
    this.newElement = function(type, px, py) {

        var oElement = null;
        
        switch(type){

            case EElementType.eTImage:
                oElement = new Image();
                oElement.id = this.generateId(type);
                oElement.nickName = this.generateNickName(oElement.id, EAppLabels.eTImageNickNamePrefix);
                oElement.x = px - Math.abs(parseInt(oElement.width)/2);
                oElement.y = py - Math.abs(parseInt(oElement.height)/2);
                break;
            case EElementType.eTLabel:
                oElement = new Label();
                oElement.id = this.generateId(type);
                oElement.nickName = this.generateNickName(oElement.id, EAppLabels.eTLabelNickNamePrefix);
                oElement.x = px;
                oElement.y = py;
                break;
        }
        return oElement;
    }
    
    this.addElement = function(oElement) {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        var oUITreeView = UIInstance.getUITreeViewInstance();

        //seleciona o elemento
        _oClassOwner.setSelectedElement(oElement);
        if(oElement != null){
            //adiciona o novo elemento no conteudo do projeto
            _oClassOwner.addElementOnProjectContent(oElement);
            //insere o novo elemento em formato SVG no layout
            oUIMapLayoutArea.insertSVGElement(oElement);
            //adiciona a descricao do elemento criado como um item na arvore de elementos
            oUITreeView.addNodeTreeView(oElement.nickName, oElement.type);
            //altera a area de composicao para o modo de selecao de elemento
            oUIMapLayoutArea.setElementTypeToDraw(EElementType.eNone);
        }
    }

    this.removeElement = function(elementId) {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        var oUITreeView = UIInstance.getUITreeViewInstance();

        var oOldElement = _oClassOwner.getSelectedElement();
        if(oOldElement != null){
            //remove o elemento do conteudo do projeto
            _oClassOwner.remElementOnProjectContent(elementId);
            //remove o elemento em formato SVG do layout
            oUIMapLayoutArea.removeSVGElement(elementId);
            //remove a descricao do elemento criado como um item na arvore de elementos
            oUITreeView.remNodeTreeView(oOldElement.nickName);
            //define nenhum elemento selecionado
            _oClassOwner.setSelectedElement(null);
            UIInstance.getUIMapLayoutAreaInstance().onClickSVGLayout();
        }
    }

    this.editPropertiesElement = function(oElement) {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        
        //atualiza o elemento selecionado
        _oClassOwner.setSelectedElement(oElement);
        if(oElement != null){
            //atualiza as propriedades do elemento no conteudo do projeto
            _oClassOwner.updateElementOnProjectContent(oElement);
            //edita as propriedades do elemento em formato SVG no layout
            oUIMapLayoutArea.editPropertiesSVGElement(oElement);
        }
        //atualiza a posicao do seletor de elemento
        oUIMapLayoutArea.setSelector();
    }

    this.editPropertiesLayout = function(oLayout) {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        //define nenhum elemento para edicao
        _oClassOwner.editPropertiesElement(null);
        //atualiza as propriedades do layout no conteudo do projeto
        _oClassOwner.updateLayoutOnProjectContent(oLayout);
        //edita as propriedades do layout em formato SVG
        oUIMapLayoutArea.editPropertiesSVGLayout(oLayout);
    }

    this.loadCompositionEnvironment = function(jsonProjectContent){

        this.setProjectContent(jsonProjectContent);
        this.prepareLayout();
        this.addElementsOnLayout();
    }

    this.unloadCompositionEnvironment = function(){

        this.removeElementsFromLayout();
        this.updateLayoutOnProjectContent(this.getLayout());
        UIInstance.getUIPropertiesInstance().hideAllProperties();
    }

    this.prepareLayout = function(){

        var oLayout = _oClassOwner.getLayout();
        
        oLayout.id = _projectContent.layout.id;
        oLayout.type = _projectContent.layout.type;
        oLayout.orientation = _projectContent.layout.orientation;
        oLayout.x = _projectContent.layout.x;
        oLayout.y = _projectContent.layout.y;
        oLayout.width = _projectContent.layout.width;
        oLayout.height = _projectContent.layout.height;
        oLayout.fill = _projectContent.layout.fill;
        oLayout.stroke = _projectContent.layout.stroke;
        oLayout.strokeWidth = _projectContent.layout.strokeWidth;

        _oClassOwner.setLayout(oLayout);
        UIInstance.getUIMapLayoutAreaInstance().onClickSVGLayout();
    }

    this.updateLayoutOnProjectContent = function(oLayout){
        
        _projectContent.layout.id = oLayout.id;
        _projectContent.layout.type = oLayout.type;
        _projectContent.layout.orientation = oLayout.orientation;
        _projectContent.layout.x = oLayout.x;
        _projectContent.layout.y = oLayout.y;
        _projectContent.layout.width = oLayout.width;
        _projectContent.layout.height = oLayout.height;
        _projectContent.layout.fill = oLayout.fill;
        _projectContent.layout.stroke = oLayout.stroke;
        _projectContent.layout.strokeWidth = oLayout.strokeWidth;
    }

    this.addElementsOnLayout = function() {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        var oUITreeView = UIInstance.getUITreeViewInstance();
        var projectContentTmp = this.getProjectContent();
        var tam = projectContentTmp.layout.elements.length;
        var oElement = null;

        for (var i = 0; i < tam; i++) {
            oElement = projectContentTmp.layout.elements[i];
            //insere o novo elemento em formato SVG no layout
            oUIMapLayoutArea.insertSVGElement(oElement);
            //adiciona a descricao do elemento criado como um item na arvore de elementos
            oUITreeView.addNodeTreeView(oElement.nickName, oElement.type);
        }
    }

    this.removeElementsFromLayout = function() {

        var oUIMapLayoutArea = UIInstance.getUIMapLayoutAreaInstance();
        var oUITreeView = UIInstance.getUITreeViewInstance();
        var projectContentTmp = this.getProjectContent();
        var tam = projectContentTmp.layout.elements.length;
        var oElement = null;

        while (tam > 0) {
            oElement = projectContentTmp.layout.elements[tam-1];
            //remove o elemento em formato SVG do layout
            oUIMapLayoutArea.removeSVGElement(oElement.id);
            //remove a descricao do elemento criado como um item na arvore de elementos
            oUITreeView.remNodeTreeView(oElement.nickName);
            tam = tam - 1;
        }
    }

    this.addElementOnProjectContent = function(oElement) {
        _projectContent.layout.elements.push(oElement);
    }

    this.remElementOnProjectContent = function(id) {

        //procura o id do elemento a ser removido
        for (var i = 0; i < _projectContent.layout.elements.length; i++) {
            if (id == _projectContent.layout.elements[i].id) {
                //remove o elemento
                for (var j = i; j < _projectContent.layout.elements.length-1; j++) {
                    _projectContent.layout.elements[j] = _projectContent.layout.elements[j+1];
                }
                _projectContent.layout.elements.pop();
                break;
            }
        }
    }

    this.updateElementOnProjectContent = function(oElement) {

        //procura o id do elemento a ser atualizado
        for (var i = 0; i < _projectContent.layout.elements.length; i++) {
            if (oElement.id == _projectContent.layout.elements[i].id) {
                _projectContent.layout.elements[i] = oElement;
                break;
            }
        }
    }
    
    this.getElementById = function(id) {

        var oElement = null;
        for (var i = 0; i < _projectContent.layout.elements.length; i++) {
            if (id == _projectContent.layout.elements[i].id) {
                oElement = _projectContent.layout.elements[i];
            }
        }
        return oElement;
    }

    this.getElementByNickName = function(nickName) {

        var oElement = null;
        for (var i = 0; i < _projectContent.layout.elements.length; i++) {
            if (nickName == _projectContent.layout.elements[i].nickName) {
                oElement = _projectContent.layout.elements[i];
            }
        }
        return oElement;
    }

    this.getElementTypeById = function(id) {
        
        var elementType = EElementType.eNone;
        for (var i = 0; i < _projectContent.layout.elements.length; i++) {
            if (id == _projectContent.layout.elements[i].id) {
                elementType = _projectContent.layout.elements[i].type;
            }
        }
        return elementType;
    }

    /**
     * Gera um novo id de elemento
     *
     * @param {String} elementType tipo de elemento. Ex. formato de entrada: "timage"
     * @return {String} novo id gerado. Ex. formato de saida: "timage-10"
     */
    this.generateId = function(elementType){
        
        var newId = null;
        var idTest = null;
        
        for(var i=1;;i++) {
            idTest = elementType+"-"+i;
            if( this.getElementById(idTest) == null ) {
                newId = idTest;
                break;
            }
        }
        return newId;
    }

    /**
     * Gera um apelido para o elemento
     *
     * @param {String} elementId id de elemento. Ex. formato de entrada: "timage-10"
     * @param {String} elementNickNamePrefix prefixo de apelido do elemento. Ex. formato de entrada: "imagem"
     * @return {String} novo apelido gerado. Ex. formato de saida: "imagem-10"
     */
    this.generateNickName = function(elementId, elementNickNamePrefix){

        var newNickName = null;
        
        if(elementId != null) {
            var strings = elementId.split("-");
            newNickName = elementNickNamePrefix+"-"+strings[1];
        }
        return newNickName;
    }

    this.setSelectedElement = function(oElement) {
        _oSelectedElement = oElement;
    }
    
    this.getSelectedElement = function() {
        return _oSelectedElement;
    }

    this.getProjectContent = function() {
        return _projectContent;
    }

    this.setProjectContent = function(projectContent) {
        _projectContent = this.newProjectContent();
        _projectContent = projectContent;
    }

    this.newProjectContent = function() {
        return new Array();
    }

    this.getLayout = function(){
        return _oLayout;
    }

    this.setLayout = function(oLayout){
        _oLayout = oLayout;
    }
    
    /**
     * Chamada do inicializador da classe
     */
    this.init();
}


